plinstrument:
{
calc:"
// (based on V-SHOW X760)

#include	colorconv
#include	hsv
#include	ledref
#include	o_pan
#include	o_tilt
#include	o_shutter
#include	o_dimmer
#include	o_color
#include	o_pix


// controls
cMod;
cShw;
cPan; cTlt; cSpd; cPTm; cPTs; cFnc; cDim; cSht; cPix; cCol; cCMs;

// parameters
pRPn;
pRTl;
pMod;

// constants
kPosY = 0.000;
kDia = 0.14;
kBaseWid = 0.23;
kBaseHi  = 0.08;
kBaseDep = 0.14;
kArmDep  = 0.09;
kArmWid  = 0.26;
kCenterHi = 0.26;
kZBack  =  0.055;
kZFront = -0.05;
kHeadWid = 0.17;
kHeadHi  = 0.17;

kSource = LEDRefConv(9 * 10, kDia, kLEDRefWatt_RGBW, kLEDRefDia_RGBW, kLEDRefSrc_RGBW);
kWhite = kLEDRefWhite_RGBW;
kCnt = 2;	// (?)
kSpread = Spread(kCnt, 0.5, 5);	// (?) (of similar device)


// protocol parameters
CENTER[1] = kCenterHi;
PAN;
TILT;
LIGHT;
SHAPE;
CTLS;

PRM=1;
CTL;


// macro, show
kMacroSpeedMin = 0.1;	// (?)
kMacroSpeedMax = 1;		// (?)
kPanRange = 32;
kTltRange = 64;

gPTMacPh;
gCoMacPh;

// proxy
_cPan; _cTlt; _cSpd; _cDim; _cSht; _cCol;

PTMacro#
(
	pa = 2 * M_PI * gPTMacPh;
	_cPan = 128 + kPanRange * sin(pa);
	_cTlt = 128 + kTltRange * cos(pa);
);


MacroTime#
(
	(pMod == 0)?
	(
		ms = 128;
		cs = 128;
	)
	:
	(
		ms = cPTs;
		cs = cCMs;
	);

	ps = ParamSqr(kMacroSpeedMin, kMacroSpeedMax, 0, 255, ms);
	gPTMacPh = Cycle(gPTMacPh + ps * $0);
	ps = ParamSqr(kMacroSpeedMin, kMacroSpeedMax, 0, 255, cs);
	gCoMacPh = Cycle(gCoMacPh + ps * $0);

	(pMod == 0)?
	(
		PTMacro();
		_cSpd = 0;
		_cDim = (cShw < 8)? 0 : 255;
		_cSht = 0;
		_cCol = 255;
	)
	:
	(
		(cPTm < 16)?
		(
			_cPan = cPan;
			_cTlt = cTlt;
			_cSpd = cSpd;
		)
		:
		(
			PTMacro();
			_cSpd = 0;
		);
		_cDim = cDim;
		_cSht = cSht;
		_cCol = cCol;
	);
);


// pan, tilt

gPan  = PanNew(540);	// (?)
gTilt = TiltNew(220);	// (?)

PanTiltTime#
(
	PanSetInv(gPan,   pRPn);
	TiltSetInv(gTilt, pRTl);

	sn = CtlN(0, 255, _cSpd);
	PanSetSpeedN(gPan, sn);
	TiltSetSpeedN(gTilt, sn);

	c  = PanPos( gPan,  $0, _cPan / 256);
	c += TiltPos(gTilt, $0, _cTlt / 256);
	c
);


// shutter

ShutterTimeO#	// (time, obj, ctl)
(
	so = $1;
	sc = $2;

	(sc < 16)?		// open
	(
		ShutterOpen(so);
	)
	:(sc < 132)?	// strobe
	(
		ShutterStrobe(so, $0, CtlN(16, 131, sc));
	)
	:(sc < 140)?	// open
	(
		ShutterOpen(so);
	)
	:(sc < 182)?	// opening
	(
		ShutterOpening(so, $0, CtlN(140, 181, sc));
	)
	:(sc < 190)?	// open
	(
		ShutterOpen(so);
	)
	:(sc < 232)?	// closing
	(
		ShutterClosing(so, $0, CtlN(190, 231, sc));
	)
	:(sc < 240)?	// open
	(
		ShutterOpen(so);
	)
	:(sc < 248)?	// random
	(
		ShutterStrobeRandom(so, $0, 0.5);
	)
	:
	(
		ShutterOpen(so);
	);
);

gShutter = ShutterNew(1, 25, 1 / 30);	// (?)

ShutterTime#
(
	ShutterTimeO($0, gShutter, _cSht);
);


// dimmer

gDimmer = DimmerNew();

DimmerTime#
(
	DimmerLev(gDimmer, $0, _cDim / 255);
);


// color
kFull = Vec(1, 1, 1, 1);
kPixs = 9;
gPixs = PixNew(kPixs);


ColorTime#
(
	(_cCol < 8)?		// no macro
	(
		(pMod == 1)?
		(
			p = cPix[0];
			c = Vec(p.cR / 255, p.cG / 255, p.cB / 255, p.cW / 255);
			PixSetAll(gPixs, c);
		)
		:
		(
			@(i < kPixs)
			(
				p = cPix[i];
				c = Vec(p.cR / 255, p.cG / 255, p.cB / 255, p.cW / 255);
				PixSet(gPixs, i, c);
				++i;
			);
		);
	)
	:(_cCol < 128)?
	(	// (simple hue?)
		h = ParamLin(0, 1, 8, 128, _cCol);
		c = RGBfromHSV(h, 1, 1);
		PixSetAll(gPixs, c);
	)
	:
	(	// (simple rainbow?)
		c = RGBfromHSV(gCoMacPh, 1, 1);
		PixSetAll(gPixs, c);
	);
);


// protocol methods

UPDATE#
(
	MacroTime($0);
	dir = PanTiltTime($0);
	ShutterTime($0);
	DimmerTime($0);
	ColorTime($0);

	PRM?
	(
		cMod = pMod;
		CTLS = 1;

		// setup light
		l = LIGHT[0];
		l.pos[1] = kPosY;
		l.pos[2] = kZFront;
		l.dia = kDia;
		l.spdh = kSpread;
		l.spdv = kSpread;
		l.cnt = kCnt;
		LIGHT[0] = l;
	);

	(dir | PRM)?
	(
		PAN = gPan.cur;
		TILT = 90 + gTilt.cur;
		SHAPE = MovingShape(kBaseWid, kBaseHi, kHeadWid, kHeadHi, kZFront, kZBack, kCenterHi, PAN, TILT, kBaseDep, kArmDep, kArmWid);
	);

	(
		
		// main light
		c = PixAverage(gPixs);
		c = RGBfromRGBW(c, kWhite);
		c = VecScale(c, kSource * gDimmer.cur * gShutter.cur);
		
		// setup light
		l = LIGHT[0];
		l.color = c;
		LIGHT[0] = l;
	);

	PRM = CTL = 0;
);

";


chmap:
"cShw",
"cPan.w cTlt.w cSpd cPTm cPTs cFnc cDim cSht cPix(cR cG cB cW)[1] cCol cCMs",
"cPan.w cTlt.w cSpd cPTm cPTs cFnc cDim cSht cPix(cR cG cB cW)[9] cCol cCMs";


ctlprop:
{
	ctls:
	{
		id:cPTm;
		name:PT Macro;
	},
	{
		id:cPTs;
		name:PT Speed;
	},
	{
		id:cCMs;
		name:ColorSpeed;
	},
	{
		id:cShw;
		name:Show;
		ini:8;
	};
};


prm:
{
	controls:
	{
		type:check;
		id:pRPn;
		name:"-Pan";
	},
	{
		type:check;
		id:pRTl;
		name:"-Tilt";
	},
	{
		type:selector;
		id:pMod;
		name:Mode;
		ini:1;
		items:
		{
			text:1ch;
			value:0;
		},
		{
			text:16ch;
			value:1;
		},
		{
			text:48ch;
			value:2;
		};
	};
};

};
